package pl.edu.agh.jemo.evolution.objfunc.impl;

import javax.swing.JPanel;

import pl.edu.agh.jemo.evolution.genotype.impl.DoubleGenotype;
import pl.edu.agh.jemo.evolution.objfunc.ClassicObjectiveFunction;
import pl.edu.agh.jemo.evolution.objfunc.ObjectiveFunction;
import pl.edu.agh.jemo.evolution.operator.common.DomainControl;
import pl.edu.agh.jemo.evolution.operator.mutation.impl.RadialMutation;
import pl.edu.agh.jemo.evolution.specimen.Specimen;

public class ExtremaFinderObjectiveFunction extends ClassicObjectiveFunction {

	private Double radius = .01;
	private int sampleSize = 300;
	private Double dominationRatio = .99;

	private RadialMutation mutation = new RadialMutation();

	public ExtremaFinderObjectiveFunction() {
		mutation.setDomainControl(DomainControl.MOVE_TO_BORDER);
		mutation.setImproveSpecimen(false);
		mutation.setMutationChance(1.);
		mutation.setRadius(radius);
	}
	
	@Override
	public Double calculateValue(Specimen specimen) {

		ObjectiveFunction firstObjectiveFun = specimen.getObjectiveFunctions().get(0);
		
		Double currentValue = firstObjectiveFun.calculateValue(specimen);
		int dominatedCount = 0;
		
		try {
			for (int i = 0; i < sampleSize; i++) {
				Specimen sample = new Specimen();
				sample.init(specimen.getObjectiveFunctions(),DoubleGenotype.class);
				mutation.performMutation(sample);
				if (currentValue >= firstObjectiveFun.calculateValue(sample)) {
					dominatedCount++;
				}
				
			}

		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		
		//if specimen dominates 95% of others then add it to front0 --- to musi byc w dominationrelation
/*		if(dominatedCount*1./sampleSize > dominationRatio) {
			dominatedCount=sampleSize;
		}
*/		return 1.*dominatedCount/sampleSize;
	}

	@Override
	public JPanel getConfigPanel() {
		// TODO Manio zaimplementuj to
		return null;
	}

	@Override
	public Double getMaxValue() {
		return 1.;
	}

	@Override
	public Double getMinValue() {
		return 0.;
	}

	public Double getRadius() {
		return radius;
	}

	public void setRadius(Double radius) {
		this.radius = radius;
		mutation.setRadius(radius);
	}

	public int getSampleSize() {
		return sampleSize;
	}

	public void setSampleSize(int sampleSize) {
		this.sampleSize = sampleSize;
	}

	/**
	 * Returns String format object data.
	 * 
	 * @return String consisting of name of class and current nicheRadius.
	 */
	@Override
	public String toString() {
		return String.format("Extrema finder:  (Radius: %f, Sample size: %d, Domination ratio: %f)", radius, sampleSize,dominationRatio);
	}

	public Double getDominationRatio() {
		return dominationRatio;
	}

	public void setDominationRatio(Double dominationRatio) {
		this.dominationRatio = dominationRatio;
	}

}
